#pragma once
#include "bspline_curve.h"

namespace shermit {
	//////////////////////////////////////////////////////////////////////
	//
	//  CubicBSplineCurve on Cuda Device
	//
	//////////////////////////////////////////////////////////////////////
	template<typename Float_t>
	class BSplineCurve<Float_t, 3, DeviceType::GPU> {
	public:
		using vec_t = nv::vec2<Float_t>;
		GENERAL BSplineCurve<Float_t, 3, DeviceType::GPU>();

		GENERAL int degree() const;  // max degree of the curve's polynomials
		GENERAL int nControlPts() const;  // num of control points
		GENERAL int nKnots() const;  // num of knots
		const vec_t* getControlPts() const; // get control points array
		GENERAL Float_t tMin() const;  // parameter t in range [tMin, tMax)
		GENERAL Float_t tMax() const;

		/*N_{i,3}(t)*/
		__device__ Float_t baseFuncVal(int i, Float_t t) const;
		__device__ vec_t at(Float_t t) const;
		__device__ vec_t df1(Float_t t) const;
		__device__ vec_t df2(Float_t t) const;
		__device__ vec_t df(Float_t t, unsigned int order) const; // k-order differential of f(t)
		__device__ vec_t tangent(Float_t t) const;
		__device__ vec_t normal(Float_t t) const;  // pointing away from the curvature circle
		__device__ Float_t curvature(Float_t t) const;

		void copyToHost(BSplineCurve<Float_t, 3, DeviceType::CPU>& h_curve) const;

		void setControlPts(const vec_t* pts, int num_pts, DeviceType from);
		void deallocate();

		vec_t* control_pts;
		int num_control_pts;
	};
}
